#include "PatientValueEventServer.h"
#include "Patient.h"
#include <iostream>

using namespace std;

PatientValueEventServer::PatientValueEventServer(IReactor<SOCKET>* _reactor, IInfo *info)
	:ServiceHandler(_reactor), response(NO_VALUE), myServer(info)
{
	patient = new Patient();
}


PatientValueEventServer::~PatientValueEventServer(void)
{
	delete patient;
}

bool PatientValueEventServer::open(SOCK_Stream* st)
{
	peer().set_handle(st->get_handle());
	handle.setConnection(st->get_handle());
	reactor->register_handler(this, INIT_EVENT);
	return true;
}

void PatientValueEventServer::handle_event(Handler<SOCKET> handle, Event_Type et)
{
	if(et == INIT_EVENT)
	{
		clientConnected();		 // Registers READ_EVENT
	}
	else if ( et == READ_EVENT)
	{
		requestRecieved();		// Registers WRITE_EVENT
	}
	else if (et == WRITE_EVENT)
	{
		switch(response)
		{
		case NO_PATIENT:
			noPatient();		// Registers READ_EVENT
			break;
		case OK_PATIENT:
			sendPatient();		// Registers READ_EVENT
			break;
		case REQ_EXIT:
			exit();				// Closes socket
			break;
		case INVALID_REQ:
			invalidRequest();	// Registers READ_EVENT
			break;
		default:
			cout << "Nothing to send" << endl;
		}
	}

}


void PatientValueEventServer::clientConnected()
{
	cout << endl << endl <<"Server connected. Waiting for client requests." << endl;
	reactor->remove_handler(this,INIT_EVENT);
	reactor->register_handler(this,READ_EVENT);
}

void PatientValueEventServer::requestRecieved()
{	
	reactor->remove_handler(this,READ_EVENT);

	const size_t len = 50;
	char buf[len] = {};
	int recievedLength = stream.recv(&buf,len,0);
	
	if(recievedLength > 0)
		buf[recievedLength]='\0';

	if(strlen(buf) > 0)
	{
		if(strcmp(buf,CLOSE_CONNECTION) == 0)
		{
			response = REQ_EXIT;
		}
		else
		{
			cout << endl << "Patient requested: " << buf << endl;
			
			if(!verifyRequest(buf))
			{
				response = INVALID_REQ;
			}
			else
			{
				if(myServer->get(buf, patient))
				{
					response = OK_PATIENT;
				}
				else
					response = NO_PATIENT;
			}
		}

		reactor->register_handler(this,WRITE_EVENT);
	}
}

bool PatientValueEventServer::verifyRequest(char* value)
{
	int retVal = 0;
	for(int i = 0; i < strlen(value); i++)
	{
		if(value[i] >= '0' && value[i] <= '9')
			retVal++;
	}
	if(retVal==strlen(value))
		return true;
	else
		return false;
}

void PatientValueEventServer::exit()
{
	reactor->remove_handler(this,WRITE_EVENT);
	peer().send(CLOSE_CONNECTION,0);
	::exit(0);
}

void PatientValueEventServer::sendPatient()
{
	reactor->remove_handler(this,WRITE_EVENT);
	peer().send(patient->toString(unitSeparator).c_str(),0); //TODO send correct patient
	cout << "Transfering patientdata."<< endl;
	reactor->register_handler(this,READ_EVENT); //wait for request
}

void PatientValueEventServer::noPatient()
{
	reactor->remove_handler(this,WRITE_EVENT);
	peer().send("NO_PATIENT",0);
	reactor->register_handler(this,READ_EVENT); //wait for request
}

void PatientValueEventServer::invalidRequest()
{
	reactor->remove_handler(this,WRITE_EVENT);
	peer().send("INVALID_REQUEST",0);
	reactor->register_handler(this,READ_EVENT); //wait for request
}
